package edu.friday.service.impl;

import edu.friday.common.constant.UserConstants;
import edu.friday.common.result.TableDataInfo;
import edu.friday.model.SysUser;
import edu.friday.model.vo.SysUserVO;
import edu.friday.repository.SysRoleRepository;
import edu.friday.repository.SysUserRepository;
import edu.friday.service.SysRoleService;
import edu.friday.service.SysUserService;
import edu.friday.utils.BeanUtils;
import edu.friday.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    SysUserRepository sysUserRepository;
    @Autowired
    SysRoleService sysRoleService;

    @Override
    public TableDataInfo selectUserList(SysUserVO sysUserVO, Pageable pageable) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyPropertiesIgnoreEmpty(sysUserVO, sysUser);
        sysUser.setDelFlag("0");

        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("userName", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("phonenumber", ExampleMatcher.GenericPropertyMatchers.contains());
        //Example用法:  select * from sysUser where exampleMatcher sysUser数据库对象，exampleMatcher条件
        Example<SysUser> example = Example.of(sysUser, exampleMatcher);
        Page<SysUser> rs = sysUserRepository.findAll(example, pageable);
        return TableDataInfo.success(rs.toList(), rs.getTotalElements());
    }

    @Override
    @Transactional
    public boolean insertUser(SysUserVO sysUserVO) {
        //1.sys_user
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserVO, sysUser);
        sysUser.setDelFlag("0");
        sysUserRepository.save(sysUser);
        //2.sys_user_role
        sysUserVO.setUserId(sysUser.getUserId());
        insertUserRole(sysUserVO);
        return null != sysUser.getUserId();
    }

    @Transactional
    public int insertUserRole(SysUserVO user) {
        Long[] roles = user.getRoleIds();
        if (StringUtils.isNull(roles) || roles.length == 0) {
            return 0;
        }
        Long[] userIds = new Long[roles.length];
        Arrays.fill(userIds, user.getUserId());
        return sysUserRepository.batchInsertUserRole(userIds, roles);
    }

    @Override
    public String checkUserNameUnique(String userName) {
        SysUser sysUser = new SysUser();
        sysUser.setUserName(userName);
        return count(sysUser);
    }

    private String count(SysUser sysUser) {
        Example<SysUser> example = Example.of(sysUser);
        long count = sysUserRepository.count(example);
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkPhoneUnique(SysUserVO sysUserVO) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserVO, sysUser);
        return checkUnique(sysUser);
    }

    private String checkUnique(SysUser sysUser) {
        Example<SysUser> example = Example.of(sysUser);
        SysUser info = findOne(example);
        if (StringUtils.isNotNull(info)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    private SysUser findOne(Example<SysUser> example) {
        List<SysUser> sysUserList = sysUserRepository.findAll(example, PageRequest.of(0, 1)).toList();
        if (sysUserList.isEmpty()) {
            return null;
        }
        return sysUserList.get(0);
    }

    @Override
    public String checkEmailUnique(SysUserVO sysUserVO) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserVO, sysUser);
        return checkUnique(sysUser);
    }

    @Override
    @Transactional
    public int deleteByUserIds(Long[] userIds) {
        return sysUserRepository.deleteByUserIds(userIds);
    }

    @Override
    @Transactional
    public boolean updateUser(SysUserVO sysUserVO) {
        //1.delete sys_user_role
        sysUserRepository.deleteUserRoleByUserId(sysUserVO.getUserId());
        //2.update sys_user
        Optional<SysUser> op = sysUserRepository.findById(sysUserVO.getUserId());
        SysUser sysUser = op.get();
        BeanUtils.copyPropertiesIgnoreNull(sysUserVO, sysUser);//页面值sysUserVO 修改后 存储到 数据库中数据对象sysUser
        sysUserRepository.save(sysUser);
        //3.add sys_user_role
        insertUserRole(sysUserVO);
        return null != sysUser.getUserId();
    }

    @Override
    public List<Long> selectRoleListByUserId(Long userId) {
        return sysRoleService.selectRoleIdsByUserId(userId);
    }

    @Override
    public SysUser selectUserById(Long userId) {
        SysUser sysUser =new SysUser();
        sysUser.setUserId(userId);
        sysUser.setDelFlag("0");
        return sysUserRepository.findOne(Example.of(sysUser)).get();
    }

    @Override
    public SysUser selectUserByUserName(String userName) {
        SysUser sysUser =new SysUser();
        sysUser.setUserName(userName);
        sysUser.setDelFlag("0");
        Example<SysUser> example = Example.of(sysUser);
        return findOne(example);
    }
}
